package com.example.schedule;

import cn.hutool.core.io.resource.InputStreamResource;
import cn.hutool.core.io.resource.MultiResource;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.sun.org.apache.xpath.internal.operations.Bool;
import com.sun.org.apache.xpath.internal.operations.Mult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p> ScheduleApi </p>
 *
 * @author Stranger.
 * @since 2022/6/6 11:19
 */
@Controller
@RequestMapping("/api")
@Slf4j
public class ApiController {
    @Value("${cross-network.authId}")
    private String crossAuthId;
    @Value("${cross-network.authPwd}")
    private String crossAuthPwd;
    @Value("${cross-network.url}")
    private String crossUrl;
    @Value("${schedule.openHeader}")
    private Boolean openHeader;

    @GetMapping("/token")
    @ResponseBody
    public Map<String,String> token() {
        String token = ScheduleConstants.TOKEN.get(ScheduleConstants.TOKEN_KEY);
        if (StrUtil.isBlank(token)) {
            log.info("缓存中token为空！");
            // 手动请求token
            token = handleToken();
        }
        return ScheduleConstants.TOKEN;
    }

    @GetMapping("/getToken")
    @ResponseBody
    public String getToken() {
        return handleToken();
    }

    private String handleToken() {
        String result = null;
        try {
            log.info("------手动执行token------");
            Map<String, Object> map = new HashMap<>();
            map.put("authId", crossAuthId);
            map.put("authPwd", crossAuthPwd);
            log.info("请求地址:"+crossUrl+"\n 请求参数:"+map.toString());
            result = HttpUtil.post(crossUrl, map);
            if (StrUtil.isNotBlank(result) && result.indexOf("error") != -1) {
                return "";
            }
            ScheduleConstants.TOKEN.put(ScheduleConstants.TOKEN_KEY, result);
            ScheduleConstants.TOKEN.put(ScheduleConstants.TOKEN_TIME, String.valueOf(System.currentTimeMillis()/1000));
        } catch (Exception e) {
            log.info("获取认证token失败:{}", e.getMessage());
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 下载文件
     * @param url url
     * @param filename 文件名带后缀
     * @param response 返回
     * @return void
     * @author Stranger.
     * @since 2022/7/28
     */
    @GetMapping("/download")
    public void download(String url, String filename, String systemKey, String systemFlag,
                         String attachName,
                         HttpServletResponse response) {
        HttpResponse httpResponse = null;
        if (StrUtil.isNotBlank(url)) {
            url = url.replace(" ", "");
        }
        if (StrUtil.isNotBlank(attachName)) {
            attachName = attachName.replace(" ", "");
        }
        if (StrUtil.isNotBlank(filename)) {
            filename = filename.replace(" ", "");
        }
        if(url.contains("?")){
            url += "&attachName=" + attachName + "&systemKey=" + systemKey + "&systemFlag=" + systemFlag;
        }else{
            url += "?attachName=" + attachName + "&systemKey=" + systemKey + "&systemFlag=" + systemFlag;
        }

        // 部署时添加header
        if (openHeader) {
            httpResponse = HttpRequest.get(url)
                    .header("auth-token", ScheduleConstants.TOKEN.get(ScheduleConstants.TOKEN_KEY))
                    .setFollowRedirects(true).timeout(-1).executeAsync();
        } else {
            httpResponse = HttpRequest.get(url)
                    .setFollowRedirects(true).timeout(-1).executeAsync();
        }

        if (httpResponse.isOk()) {
            byte[] byteArr = httpResponse.bodyBytes();
            response.setContentType("application/octet-stream");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Content-Disposition", " attachment; filename=" + filename);
            OutputStream outputStream = null;
            try {
                outputStream = response.getOutputStream();
                outputStream.write(byteArr);
                outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else {
            throw new HttpException("Server response error with status code: [{}]", new Object[]{response.getStatus()});
        }
    }


    /**
     * @description:上传文件,保存到pc端
     * @param file
     * @param url
     * @param proInstId
     * @param systemKey
     * @param systemFlag
     * @param type
     * @param groupId
     * @param response
     */
    @RequestMapping("/documentUpload")
    public void documentUpload(MultipartFile[] file,String url, String proInstId, String systemKey, String systemFlag,
                         String type, String groupId,
                         HttpServletResponse response) {
        if (file == null || file.length == 0) {
            throw new HttpException("未选择文件");
        }

        HttpResponse httpResponse = null;
        log.info("-----------接口转发地址url：{}", url);
        if(url.contains("?")){
            url += "&proInstId=" + proInstId + "&type=" + type + "&groupId=" + groupId + "&systemKey=" + systemKey + "&systemFlag=" + systemFlag;
        }else{
            url += "?proInstId=" + proInstId + "&type=" + type + "&groupId=" + groupId + "&systemKey=" + systemKey + "&systemFlag=" + systemFlag;
        }
        log.info("-----------接口转发完整地址url：{}", url);
        File files = null;
        try {
            MultiResource multiResource = new MultiResource(
                    Arrays.stream(file)
                            .map(multipartFile -> {
                                try {
                                    return new InputStreamResource(multipartFile.getInputStream(), multipartFile.getOriginalFilename());
                                } catch (IOException e) {
                                    throw new HttpException("输入流打开失败", e);
                                }
                            }).collect(Collectors.toList())
            );
            log.info("-------------multiResource:{}", multiResource.toString());
            // 部署时添加header
            if (openHeader) {
                // 调用第三方url实现文件上传，携带file
                httpResponse = HttpRequest.post(url)
                        .header("auth-token", ScheduleConstants.TOKEN.get(ScheduleConstants.TOKEN_KEY))
                        .form("file", multiResource)
                        .form("proInstId", proInstId)
                        .form("type", type)
                        .form("groupId", groupId)
                        .form("systemKey", systemKey)
                        .form("systemFlag", systemFlag)
                        .setFollowRedirects(true).timeout(-1)
                        .executeAsync();

            } else {
                httpResponse = HttpRequest.post(url)
                        .form("file", multiResource)
                        .form("proInstId", proInstId)
                        .form("type", type)
                        .form("groupId", groupId)
                        .form("systemKey", systemKey)
                        .form("systemFlag", systemFlag)
                        .setFollowRedirects(true).timeout(-1)
                        .executeAsync();
            }
            log.info("-------------httpResponse:{}", httpResponse.toString());
            log.info("-------------isOk:{}", httpResponse.isOk());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
